// ============================================================================
//
// Copyright (C) 2009-2011 www.sc.com SC Technology Group
//
// ============================================================================
package com.cs.vessel.breakdown;

import java.util.Iterator;
import java.util.List;

import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.view.CDOQuery;
import org.eclipse.emf.common.util.EList;

import com.sc.vessel.info.model.breakdown.Accident;
import com.sc.vessel.info.model.breakdown.AttributeIdentify;
import com.sc.vessel.info.model.breakdown.Component;
import com.sc.vessel.info.model.breakdown.ConfigElement;
import com.sc.vessel.info.model.breakdown.ConfigElementSelected;
import com.sc.vessel.info.model.breakdown.Configuration;

/**
 * DOC liaoqc class global comment. Detailled comment
 */
public class CDOHibernateUtil {

    public static Component getRootCompomnent() {
        final CDOSession session = Activator.getDefault().getSession();
        final CDOTransaction transaction = session.openTransaction();
        CDOResource resource = transaction.getResource(Activator.RES_NAME); //$NON-NLS-1$
        final Component component = (Component) resource.getContents().get(0);
        try {
            transaction.commit();
        } catch (CommitException e) {
            e.printStackTrace();
        }
        return component;
    }

    public static Configuration getConfiguration() {
        final CDOSession session = Activator.getDefault().getSession();
        final CDOTransaction transaction = session.openTransaction();
        CDOResource resource = transaction.getResource(Activator.RES_CONFIG_NAME); //$NON-NLS-1$
        final Configuration configuration = (Configuration) resource.getContents().get(0);
        try {
            transaction.commit();
        } catch (CommitException e) {
            e.printStackTrace();
        }
        return configuration;
    }

    public static EList<Accident> getBreakdowns(Component containerComponent) throws CommitException {
        EList<Accident> accidents = null;
        CDOSession session = Activator.getDefault().getSession();
        CDOTransaction transaction = session.openTransaction();
        final CDOQuery orderQuery = transaction.createQuery("hql", //$NON-NLS-1$
                "select component from Component component where component.itemId=:itemId"); //$NON-NLS-1$
        orderQuery.setParameter("itemId", containerComponent.getItemId()); //$NON-NLS-1$
        final List<Component> components = orderQuery.getResult(Component.class);
        for (Iterator<Component> iterator = components.iterator(); iterator.hasNext();) {
            Component component = (Component) iterator.next();
            accidents = component.getBreakdowns();
        }
        transaction.commit();
        return accidents;
    }

    public static void deleteAccident(Accident accident) throws CommitException {
        if (accident != null) {
            Accident serverSideAccident = getAccident(accident);
            if (serverSideAccident == null) {
                return;
            }
            CDOSession session = Activator.getDefault().getSession();
            CDOTransaction transaction = session.openTransaction();
            final CDOQuery orderQuery = transaction.createQuery("hql", //$NON-NLS-1$
                    "select component from Component component where component.itemId=:itemId"); //$NON-NLS-1$
            orderQuery.setParameter("itemId", accident.getComponent().getItemId()); //$NON-NLS-1$
            final List<Component> components = orderQuery.getResult(Component.class);
            for (Iterator<Component> iterator = components.iterator(); iterator.hasNext();) {
                Component component = (Component) iterator.next();
                component.getBreakdowns().remove(serverSideAccident);
            }
            transaction.commit();
        }
    }

    /**
     * DOC liaoqc Comment method "getAccident".
     * 
     * @param accident
     * @return
     */
    private static Accident getAccident(Accident accident) {
        CDOSession session = Activator.getDefault().getSession();
        CDOTransaction transaction = session.openTransaction();
        final CDOQuery accidentQuery = transaction.createQuery("hql", //$NON-NLS-1$
                "select accident from Accident accident where accident.itemId=:itemId"); //$NON-NLS-1$
        accidentQuery.setParameter("itemId", accident.getItemId()); //$NON-NLS-1$
        final List<Accident> accidents = accidentQuery.getResult(Accident.class);
        if (accidents.size() != 0) {
            return accidents.get(0);
        }
        return null;
    }

    public static void addOrChangeAccident(Accident accident) throws CommitException {
        boolean accidentExists = checkAddOrChange(accident);
        if (!accidentExists) {
            CDOSession session = Activator.getDefault().getSession();
            CDOTransaction transaction = session.openTransaction();
            final CDOQuery orderQuery = transaction.createQuery("hql", //$NON-NLS-1$
                    "select component from Component component where component.itemId=:itemId"); //$NON-NLS-1$
            orderQuery.setParameter("itemId", accident.getComponent().getItemId()); //$NON-NLS-1$
            final List<Component> components = orderQuery.getResult(Component.class);
            for (Iterator<Component> iterator = components.iterator(); iterator.hasNext();) {
                Component component = (Component) iterator.next();
                accident.setComponent(component);
                component.getBreakdowns().add(accident);
            }
            transaction.commit();
        } else {
            CDOSession session = Activator.getDefault().getSession();
            CDOTransaction transaction = session.openTransaction();
            final CDOQuery accidentQuery = transaction.createQuery("hql", //$NON-NLS-1$
                    "select accident from Accident accident where accident.itemId=:itemId"); //$NON-NLS-1$
            accidentQuery.setParameter("itemId", accident.getItemId()); //$NON-NLS-1$
            final List<Accident> accidents = accidentQuery.getResult(Accident.class);
            if (accidents.size() == 1) {
                Accident serverSideAccident = accidents.get(0);
                copyAttributes(accident, serverSideAccident);
            }
            transaction.commit();
        }

    }

    /**
     * DOC liaoqc Comment method "copyAttributes".
     * 
     * @param accident
     * @param serverSideAccident
     */
    private static void copyAttributes(Accident accident, Accident serverSideAccident) {
        serverSideAccident.setPhenomenon(accident.getPhenomenon());
        serverSideAccident.setProcess(accident.getProcess());
        serverSideAccident.setAnalyze(accident.getAnalyze());
        serverSideAccident.setExperience(accident.getExperience());
        EList<ConfigElementSelected> configElementSelecteds = serverSideAccident.getConfigElements();
        for (int i = 0; i < configElementSelecteds.size(); i++) {
            ConfigElementSelected configElementSelected = configElementSelecteds.get(i);
            configElementSelected.setSelectedValue(accident.getConfigElements().get(i).getSelectedValue());
        }
    }

    /**
     * DOC liaoqc Comment method "checkAddOrChange".
     * 
     * @param accident
     * @return
     */
    private static boolean checkAddOrChange(Accident accident) {
        CDOSession session = Activator.getDefault().getSession();
        CDOTransaction transaction = session.openTransaction();
        final CDOQuery accidentQuery = transaction.createQuery("hql", //$NON-NLS-1$
                "select accident from Accident accident where accident.itemId=:itemId"); //$NON-NLS-1$
        accidentQuery.setParameter("itemId", accident.getItemId()); //$NON-NLS-1$
        final List<Accident> accidents = accidentQuery.getResult(Accident.class);
        if (accidents.size() != 0) {
            return true;
        }
        return false;
    }

    public static void addComponent(Component parentComponent, Component childComponent) throws CommitException {
        if (parentComponent != null) {
            CDOSession session = Activator.getDefault().getSession();
            CDOTransaction transaction = session.openTransaction();

            final CDOQuery orderQuery = transaction.createQuery("hql", //$NON-NLS-1$
                    "select component from Component component where component.itemId=:itemId"); //$NON-NLS-1$
            orderQuery.setParameter("itemId", parentComponent.getItemId()); //$NON-NLS-1$
            final List<Component> components = orderQuery.getResult(Component.class);
            for (Iterator<Component> iterator = components.iterator(); iterator.hasNext();) {
                Component component = (Component) iterator.next();
                component.getComponents().add(childComponent);
            }
            transaction.commit();
        }
    }

    public static void editConfigElementName(ConfigElement configElement, String newName) throws CommitException {
        if (configElement != null) {
            CDOSession session = Activator.getDefault().getSession();
            CDOTransaction transaction = session.openTransaction();

            final CDOQuery orderQuery = transaction.createQuery("hql", //$NON-NLS-1$
                    "select configElement from ConfigElement configElement where configElement.itemId=:itemId"); //$NON-NLS-1$
            orderQuery.setParameter("itemId", configElement.getItemId()); //$NON-NLS-1$
            final List<ConfigElement> configElements = orderQuery.getResult(ConfigElement.class);
            if (configElements.size() == 1) {
                ConfigElement queriedConfigElement = configElements.get(0);
                queriedConfigElement.setName(newName);
            }
            transaction.commit();
        }
    }

    public static void editValueIdentifyName(AttributeIdentify attributeIdentify, String newName) throws CommitException {
        if (attributeIdentify != null) {
            CDOSession session = Activator.getDefault().getSession();
            CDOTransaction transaction = session.openTransaction();

            final CDOQuery orderQuery = transaction.createQuery("hql", //$NON-NLS-1$
                    "select attributeIdentify from AttributeIdentify attributeIdentify where attributeIdentify.itemId=:itemId"); //$NON-NLS-1$
            orderQuery.setParameter("itemId", attributeIdentify.getItemId()); //$NON-NLS-1$
            final List<AttributeIdentify> attributeIdentifies = orderQuery.getResult(AttributeIdentify.class);
            if (attributeIdentifies.size() == 1) {
                AttributeIdentify queriedattributeIdentify = attributeIdentifies.get(0);
                queriedattributeIdentify.setName(newName);
            }
            transaction.commit();
        }
    }

    public static void editComponentName(Component component, String newName) throws CommitException {
        if (component != null) {
            CDOSession session = Activator.getDefault().getSession();
            CDOTransaction transaction = session.openTransaction();

            final CDOQuery orderQuery = transaction.createQuery("hql", //$NON-NLS-1$
                    "select component from Component component where component.itemId=:itemId"); //$NON-NLS-1$
            orderQuery.setParameter("itemId", component.getItemId()); //$NON-NLS-1$
            final List<Component> components = orderQuery.getResult(Component.class);
            if (components.size() == 1) {
                Component queriedComponent = components.get(0);
                queriedComponent.setName(newName);
            }
            transaction.commit();
        }
    }

    public static void addConfigElement(ConfigElement configElement) throws CommitException {
        CDOSession session = Activator.getDefault().getSession();
        CDOTransaction transaction = session.openTransaction();
        CDOResource configResource = transaction.getOrCreateResource(Activator.RES_CONFIG_NAME);
        final Configuration configuration = (Configuration) configResource.getContents().get(0);
        configuration.getElements().add(configElement);
        transaction.commit();
    }

    /**
     * DOC liaoqc Comment method "addAttributeIdentify".
     * 
     * @param configElement
     * @param attributeIdentify
     * @throws CommitException
     */
    public static void addAttributeIdentify(ConfigElement configElement, AttributeIdentify attributeIdentify)
            throws CommitException {
        if (configElement != null) {
            CDOSession session = Activator.getDefault().getSession();
            CDOTransaction transaction = session.openTransaction();

            {
                final CDOQuery orderQuery = transaction.createQuery("hql", //$NON-NLS-1$
                        "select configElement from ConfigElement configElement where configElement.itemId=:itemId"); //$NON-NLS-1$
                orderQuery.setParameter("itemId", configElement.getItemId()); //$NON-NLS-1$
                final List<ConfigElement> configElements = orderQuery.getResult(ConfigElement.class);
                if (configElements != null && configElements.size() == 1) {
                    ConfigElement component = configElements.get(0);
                    component.getAttributeIdentifies().add(attributeIdentify);
                }
            }
            transaction.commit();
        }

    }

}
